package com.aioz.service.impl;

import com.aioz.common.Result;
import com.aioz.entity.Goods;
import com.aioz.entity.Purchase;
import com.aioz.entity.User;
import com.aioz.mapper.PurchaseMapper;
import com.aioz.service.PurchaseService;
import com.aioz.utils.RedisIdWorker;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author Aioz
 * @since 2022-11-19
 */
@Service
public class PurchaseServiceImpl extends ServiceImpl<PurchaseMapper, Purchase> implements PurchaseService {

    @Resource
    private RedissonClient redissonClient;

    @Resource
    private RedisIdWorker redisIdWorker;

    @Resource
    private UserServiceImpl userService;

    @Resource
    private GoodsServiceImpl goodsService;

    private static final String KEY_ORDER = "lock:order:";

    private static final Logger log = LoggerFactory.getLogger(PurchaseServiceImpl.class);

    @Override
    @Transactional
    public Result placeAnOrder(Integer userId, Integer goodsId) throws InterruptedException {
        User user = userService.query().eq("id", userId).one();
        log.info("下单用户:   {}",user);
        //生成订单
        Purchase order = new Purchase();
        // 获取锁（可重入），指定锁的名称
        RLock lock = redissonClient.getLock(KEY_ORDER + goodsId);
        // 尝试获取锁参数分别是: 获取锁的最大等待时间（期间会重试），锁自动释放时间，时间单位
        boolean isLock = lock.tryLock(1, 10, TimeUnit.SECONDS);
        if(isLock){
            try {
                Goods goods = goodsService.query().eq("id", goodsId).one();
                if(goods.getStock() <= 0){
                    log.info("商品库存不足!");
                    return new Result().error("库存不足!");
                }
                //扣减库存
                goodsService.update().eq("id",goodsId).setSql("stock = stock - 1").update();
                log.info("下单商品:   {}",goods);
                order.setId(redisIdWorker.nextId("order"));
                order.setUserCard(userId);
                order.setBuyer(user.getUsername());
                order.setCommodity(goods.getName());
                order.setStatus(1);
                order.setTime(LocalDateTime.now());
                // 保存订单信息
                log.info("订单信息:   {}",order);
                save(order);
            }finally {
                //释放锁
                lock.unlock();
            }
        }else {
            return new Result().error("系统繁忙，请重试");
        }
        return new Result().ok(order,"下单成功!");
    }
}
